/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package retrieval;

import index.inverted.InvertedFileReader;
import index.inverted.PositionAndBytes;
import index.nested.MainIndexReader;
import index.nested.NestedIndexReader;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import util.FileListing;
import util.Timer;
import queryterm.QueryTerm;

/**
 *
 * @author Danang
 */
public class RetrieveTerm {
    public static final String uncompressed_dir = "uncompressed/";
    public static final String compressed_dir = "compressed/";
    
    InvertedFileReader invertedFile;
    MainIndexReader mainIndexTerms;
    List<NestedIndexReader> nestedIndexReader;
    HashMap<String,List> listQueryRetrieve; // <Query,List<PositionAndBytes>> untuk menampung hasil2 query
    public RetrieveTerm(String rootDir, boolean useCompress) throws Exception {
        String index_dir = rootDir;
        if (!index_dir.endsWith("/")) {
            index_dir += "/";
        }
        if (useCompress) {
            index_dir += compressed_dir;
        } else {
            index_dir += uncompressed_dir;
        }
        
        invertedFile = new InvertedFileReader(index_dir,useCompress);
        mainIndexTerms = new MainIndexReader(index_dir);
        
        nestedIndexReader = new ArrayList<NestedIndexReader>();
        File rootDirectory = new File(index_dir);
        List<File> listfiles = FileListing.getJustFileListing(rootDirectory);
        FileListing.sortFilesDescending(listfiles);
        for (File a : listfiles) {
            String name = a.getName();
            if (name.startsWith(MainIndexReader.MAIN_INDEX_TERMS) && 
                name.length()>MainIndexReader.MAIN_INDEX_TERMS.length()) {
                NestedIndexReader nested = new NestedIndexReader(a.getPath());
                nested.setNameFile(name);
                nestedIndexReader.add(nested);
            }
        }
        listQueryRetrieve = new HashMap<String, List>();
    }
    
    public void closeAllFiles() throws IOException {
        invertedFile.close();
        mainIndexTerms.close();
        for (NestedIndexReader n : nestedIndexReader) {
            n.close();
        }
    }
    
    private Long searchOnNestedIndexTerms(String token) throws IOException {
        long posBefore = 0;
        for (NestedIndexReader n : nestedIndexReader) {
            n.searchToken(token, posBefore);
            posBefore = n.getPositionRead();
        }
        return posBefore;
    }
    
    private synchronized List<PositionAndBytes> searchOnMainIndexTerms(String token, long pos) throws IOException {
        mainIndexTerms.searchToken(token, pos);
        List<PositionAndBytes> results = null;
        if (mainIndexTerms.isTokenFound()) {
            // token found
            //System.out.println("Token found");
            results = mainIndexTerms.getAllPostingListPosition();
        } else {
            // token not found
            //System.out.println("Token not found");
        }
        return results;
    }
    
    public void searchToken(String token, int field, ListDocument retrieves) throws IOException {
        //System.out.println("Searching query \""+token+"\" in field "+QueryTerm.getFieldString(field));
        Timer t = new Timer();
        long pos = 0;
        List<PositionAndBytes> results;
        if (!listQueryRetrieve.containsKey(token)) {
            if (!nestedIndexReader.isEmpty()) {
                pos = this.searchOnNestedIndexTerms(token);
            } else {
                System.out.println("Warning! No nested index file\nSearching directly on main index terms");
            }
            results = this.searchOnMainIndexTerms(token, pos);
            if (results!=null) {
                listQueryRetrieve.put(token, results);
            }
        } else {
            results = (ArrayList<PositionAndBytes>)listQueryRetrieve.get(token);
        }
        
        if (results!=null) {
            if (field==QueryTerm.All_FIELD) {
                for (PositionAndBytes p : results) {
                    String res = invertedFile.readPostingList(p.getPosition(), p.getBytesNumber());
                    retrieves.addPostingListString(token, field, res);
                }
            } else {
                PositionAndBytes p = results.get(field-1);
                String res = invertedFile.readPostingList(p.getPosition(), p.getBytesNumber());
                retrieves.addPostingListString(token, field, res);
            }
        }
        
        
        //t.printExecution_time("Finished searching "+token);
    }
    
}
